Linux C API 获取本机的 IP 地址
方法1:遍历网卡
1#include <stdio.h>
2#include <ifaddrs.h>
3#include <arpa/inet.h>
4
5int main (void)
6{
7 struct ifaddrs* ifAddrStruct = NULL;
8 getifaddrs(&ifAddrStruct); // 获得网卡的链表
9
10 while (ifAddrStruct!=NULL)
11 {
12 if (ifAddrStruct->ifa_addr->sa_family==AF_INET)
13 {
14 // IPv4
15 char address[INET_ADDRSTRLEN];
16 void* inAddr = &((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
17 inet_ntop(AF_INET, inAddr, address, INET_ADDRSTRLEN);
18
19 char netMask[INET_ADDRSTRLEN];
20 void* inNetMask = &((struct sockaddr_in *)ifAddrStruct->ifa_netmask)->sin_addr;
21 inet_ntop(AF_INET, inNetMask, netMask, INET_ADDRSTRLEN);
22
23 char broadAddr[INET_ADDRSTRLEN];
24 void* inBroadAddr = &((struct sockaddr_in *)ifAddrStruct->ifa_ifu.ifu_broadaddr)->sin_addr;
25 inet_ntop(AF_INET, inBroadAddr, broadAddr, INET_ADDRSTRLEN);
26
27 printf("IPv4 %8s: %31s \t%31s \t%31s\n", ifAddrStruct->ifa_name, address, netMask, broadAddr);
28 }
29 else if (ifAddrStruct->ifa_addr->sa_family==AF_INET6)
30 {
31 // IPv6
32 char address[INET6_ADDRSTRLEN];
33 void* inAddr = &((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
34 inet_ntop(AF_INET6, inAddr, address, INET6_ADDRSTRLEN);
35
36 char prefixMask[INET6_ADDRSTRLEN];
37 void* inPrefixMask = &((struct sockaddr_in *)ifAddrStruct->ifa_netmask)->sin_addr;
38 inet_ntop(AF_INET6, inPrefixMask, prefixMask, INET6_ADDRSTRLEN);
39
40 printf("IPv6 %8s: %31s \t%31s\n", ifAddrStruct->ifa_name, address, prefixMask);
41 }
42 ifAddrStruct=ifAddrStruct->ifa_next;
43 }
44 return 0;
45}方法2:gethostbyname
这个方法不能支持 IPv6
1#include <stdio.h>
2#include <unistd.h>
3#include <netdb.h>
4#include <arpa/inet.h>
5
6int main (void)
7{
8 // 获取 host name
9 char hostName[_SC_HOST_NAME_MAX];
10 gethostname(hostName, _SC_HOST_NAME_MAX);
11
12 // 通过 host name 获取 host entry
13 struct hostent* hostEntry = gethostbyname(hostName);
14
15 // 打印 IP 地址
16 for(int i = 0; hostEntry->h_addr_list[i]; i++)
17 {
18 printf("%s\n", inet_ntoa(*(struct in_addr*)(hostEntry->h_addr_list[i])));
19 }
20
21 return 0;
22}在
netdb.h中还有一个gethostent函数,能够遍历 host entry,但是它只能查询/etc/hosts里的值。因此,它通常只能返回127.0.0.11#include <stdio.h> 2#include <unistd.h> 3#include <netdb.h> 4#include <arpa/inet.h> 5 6int main(void) 7{ 8 struct hostent* hostEntry; 9 while((hostEntry = gethostent()) != NULL) 10 { 11 for(int i = 0; hostEntry->h_addr_list[i]; i++) 12 { 13 printf("%s\n", inet_ntoa(*(struct in_addr*)(hostEntry->h_addr_list[i]))); 14 } 15 } 16 return 0; 17}